home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-05-01 | 14.5 KB | 343 lines | [TEXT/MPS ] |
- ;
- ; File: DebuggerSupport.a
- ;
- ; Contains: Public interface to kernel services for debuggers
- ;
- ; Version: Technology: System 8
- ; Release: Universal Interfaces 3.0d3 on Copland DR1
- ;
- ; Copyright: © 1984-1996 by Apple Computer, Inc. All rights reserved.
- ;
- ; Bugs?: If you find a problem with this file, send the file and version
- ; information (from above) and the problem description to:
- ;
- ; Internet: apple.bugs@applelink.apple.com
- ; AppleLink: APPLE.BUGS
- ;
- ;
- IF &TYPE('__DEBUGGERSUPPORT__') = 'UNDEFINED' THEN
- __DEBUGGERSUPPORT__ SET 1
-
- IF &TYPE('__TYPES__') = 'UNDEFINED' THEN
- include 'Types.a'
- ENDIF
- IF &TYPE('__KERNEL__') = 'UNDEFINED' THEN
- include 'Kernel.a'
- ENDIF
- IF &TYPE('__MACHINEEXCEPTIONS__') = 'UNDEFINED' THEN
- include 'MachineExceptions.a'
- ENDIF
- IF FOR_SYSTEM8_PREEMPTIVE THEN
- ;
- ; In addition to the normal kernel API, the kernel provides a set of services
- ; which are specific to debuggers. These services are all accessed through the
- ; DebuggerSupport library.
- ; This first service is debugger registration and unregistration. For a debugger
- ; to register itself with the kernel, it calls DSRegisterDebugger. (The kernel
- ; allows only one registered debugger; multiple debuggers can be supported
- ; externally by registering a dispatching entity as the debugger.) When a debugger
- ; has successfully registered itself, it is able to receive exceptions from
- ; debuggable tasks. Unregistering is simply the reverse of registering. The
- ; kernel automatically unregisters a debugger when it terminates if the debugger
- ; has not already unregistered itself. DSRegisterDebugger should be the first
- ; call made to this library.
- ; To receive an exception, the debugger calls DSWaitForException, passing it a
- ; pointer to a DSExceptionRecord and a time limit. This call blocks until either
- ; an exception arrives or the time limit expires (pass kDurationForever to wait
- ; indefinitely). Note that this semantic essentially requires the debugger to
- ; be multithreaded.
- ; A DSExceptionRecord contains the ID of the excepted task, along with the IDs
- ; of the task's team and address space, and a message ID corresponding to the
- ; particular exception. The details of the exception are contained in the
- ; exception record's ExceptionInformation structure, which includes pointers
- ; to the task's registers and other exception state. The debugger may directly
- ; modify this exception data, and, within limits, these changes will be forced
- ; into the task's state upon resuming execution. (Changes to certain parts of
- ; the exception data, such as the privileged and interrupt enable bits of the
- ; exception MSR, will be ignored.)
- ; DSResumeFromException is used to resume the excepted task's execution or to
- ; propagate the exception on. It takes as parameters the exception ID and an
- ; exception return status. The status may be either noErr or any nonzero error
- ; code. noErr signifies that the debugger has cured the exception and the excepted
- ; task should continue execution, using the state from the exception data. Any
- ; other status value will cause the exception to be propagated to the installed
- ; exception handler, if any. If there is no installed handler, or if that handler
- ; fails to cure the exception, the exception is again presented to the debugger in
- ; another message. This time, returning a nonzero return status will cause the
- ; task to be terminated. (Double notification of exceptions allows a debugger to
- ; catch exceptions either first, last, or at both times.)
- ; Not all exceptions will be sent to the debugger. Exceptions in kernel tasks
- ; or in kernel code which runs on behalf of user tasks is not debuggable through
- ; normal means. Furthermore, exceptions occurring in privileged tasks with
- ; hardware interrupts disabled, or during execution at secondary interrupt level,
- ; or while running message system Accept functions, fall into the same category
- ; as kernel exceptions and are not sent to the debugger.
- ; The debugger may call DSHoldTasks to request the kernel to hold a task or set
- ; of tasks, making them ineligible for execution. The tasks are specified with a
- ; task ID and scope (task only, task and children, task family, or task team). If
- ; any task to be held is already blocked inside the kernel, e.g. due to a page
- ; fault, I/O operation, or message send, holding it will cause it to remain
- ; ineligible even after it has unblocked. Releasing held tasks with DSReleaseTasks
- ; allows them to become eligible again.
- ; DSGetTaskState is used to determine a task's scheduler state (runnable or blocked),
- ; and, if blocked, what its PC and SP values were at the point it blocked. If a
- ; task is running a software interrupt it will have scheduler state for both its
- ; normal execution and the execution of the software interrupt.
- ; DSReadMemory and DSWriteMemory are used to access task memory. To read memory,
- ; the debugger simply calls DSReadMemory. To modify memory, the debugger must first
- ; call DSCreateMemoryAccess to obtain a memory write access right to the desired page
- ; of memory. Using that access right, it may then call DSWriteMemory to perform the
- ; modification. DSWriteMemory performs appropriate processor cache synchronization and
- ; backing storage coordination to support modifying code memory, e.g. for instruction
- ; breakpoints. DSDeleteMemoryAccess is used to release an access right.
- ; Some implementations of the kernel and hardware may support data breakpoints. To
- ; find out what data breakpoint support (if any) is available, the debugger calls
- ; DSGetDataBreakpointInformation. DSSetDataBreakpoint is used to set or clear a
- ; data breakpoint. The implementation may cause excess exceptions which will have to
- ; be filtered out by the debugger: breakpoints may occur in the wrong address space
- ; or on an address which is outside the range specified but which lies within the
- ; resolution range supported by the implementation.
- ; Exception notification record
- ;
- DSExceptionRecord RECORD 0
- exceptedTaskID ds.l 1 ; offset: $0 (0)
- exceptedKernelProcessID ds.l 1 ; offset: $4 (4)
- exceptedTaskAddrSpaceID ds.l 1 ; offset: $8 (8)
- exceptionID ds.l 1 ; offset: $C (12)
- exception ds ExceptionInformation ; offset: $10 (16)
- sizeof EQU * ; size: $24 (36)
- ENDR
- ; typedef struct DSExceptionRecord * DSExceptionRecordPtr
-
- ; Task state record
- DSKernelState RECORD 0
- kernelState ds.l 1 ; offset: $0 (0)
- PC ds.l 1 ; offset: $4 (4)
- SP ds.l 1 ; offset: $8 (8)
- sizeof EQU * ; size: $C (12)
- ENDR
- ; typedef struct DSKernelState * DSKernelStatePtr
-
- DSTaskState RECORD 0
- taskState ds DSKernelState ; offset: $0 (0)
- swiState ds DSKernelState ; offset: $C (12)
- sizeof EQU * ; size: $18 (24)
- ENDR
- ; typedef struct DSTaskState * DSTaskStatePtr
-
- ; ID to specify write access rights to a particular page in logical memory
-
-
- ; SchedulerState values
-
- kInactiveState EQU ' '
- kPageFaultState EQU 'PFLT'
- kMessageSendState EQU 'MSND'
- kMessageReceiveState EQU 'MRCV'
- kHeldState EQU 'HELD'
- kEventFlagState EQU 'EFLG'
- kTerminatingOtherProcessState EQU 'OTRM'
- kTerminatingCurrentProcessState EQU 'CTRM'
- kTimerDelayState EQU 'DLYQ'
- kKernelQueueState EQU 'QBLK'
- kRunState EQU 'RUN '
- kSemaphoreReadState EQU 'MSRD'
- kSemaphoreWriteState EQU 'MSWR'
- kTaskStartingState EQU 'STRT'
- kTaskTerminatingState EQU 'TERM'
- ;
- ; Describes the data breakpoint facility provided by the current implementation.
- ; maxBreakpoints is the maximum number of data breakpoints available (may be zero).
- ; breakpointResolution determines the worst case range of addresses to which a data
- ; breakpoint applies, as follows: if the nominal breakpoint address is addr, the
- ; actual range of addresses breakpointed may, in the worst case, be
- ; [(addr & ~(breakpointResolution - 1)) ..
- ; (addr & ~(breakpointResolution - 1)) + breakpointResolution - 1].
- ;
- DSDataBreakpointInformation RECORD 0
- maxBreakpoints ds.l 1 ; offset: $0 (0)
- breakpointResolution ds.l 1 ; offset: $4 (4)
- sizeof EQU * ; size: $8 (8)
- ENDR
- ; typedef struct DSDataBreakpointInformation * DSDataBreakpointInformationPtr
-
-
- kDataBreakpointInformationVersion EQU 1
- ;
- ; The access types to which a data breakpoint should apply. Use
- ; kDSBreakDisable to clear a data breakpoint. Note that the implementation
- ; may not support breakpointing read and write accesses independently; in
- ; that case specifying either option will have the same effect (break on
- ; any access).
- ;
- ; typedef OptionBits DSDataBreakpointOptions
-
-
- kDSBreakDisable EQU $00000000
- kDSBreakOnReadAccess EQU $00000001
- kDSBreakOnWriteAccess EQU $00000002
- ;
- ; Debugger Services functions
- ; Register the debugger. Returns kernelIDErr if there is already a debugger
- ; registered.
- ;
- ;
- ; extern OSStatus DSRegisterDebugger(void )
- ;
- IF GENERATINGCFM THEN
- IMPORT_CFM_FUNCTION DSRegisterDebugger
- ENDIF
-
- ;
- ; Unregister the debugger. This is also done automatically by the kernel if
- ; the debugger terminates.
- ;
- ;
- ; extern OSStatus DSUnregisterDebugger(void )
- ;
- IF GENERATINGCFM THEN
- IMPORT_CFM_FUNCTION DSUnregisterDebugger
- ENDIF
-
- ; Wait specified amount of time for an exception message from the kernel.
- ;
- ; extern OSStatus DSWaitForException(DSExceptionRecord *exceptionRecord, Duration timeLimit)
- ;
- IF GENERATINGCFM THEN
- IMPORT_CFM_FUNCTION DSWaitForException
- ENDIF
-
- ;
- ; Resume execution of a task halted by an earlier exception. If exceptionReturnStatus
- ; is noErr, resume the task, else propagate the exception. If the propagated exception
- ; remains unhandled, a second exception notification will be generated.
- ;
- ;
- ; extern OSStatus DSResumeFromException(MessageID exceptionID, OSStatus exceptionReturnStatus)
- ;
- IF GENERATINGCFM THEN
- IMPORT_CFM_FUNCTION DSResumeFromException
- ENDIF
-
- ; Make the specified task(s) ineligible for execution, until released by DSReleaseTasks.
- ;
- ; extern OSStatus DSHoldTasks(TaskID taskID, TaskRelationship scope)
- ;
- IF GENERATINGCFM THEN
- IMPORT_CFM_FUNCTION DSHoldTasks
- ENDIF
-
- ; Make the specified held task(s) eligible again for execution.
- ;
- ; extern OSStatus DSReleaseTasks(TaskID taskID, TaskRelationship scope)
- ;
- IF GENERATINGCFM THEN
- IMPORT_CFM_FUNCTION DSReleaseTasks
- ENDIF
-
- ;
- ; Get the scheduler state for a task. The task may be in a software interrupt or in
- ; normal execution; if normal, state->swiState.kernelState will be kInactiveState. In
- ; either case, the appropriate state->taskState.kernelState or state->swiState.kernelState
- ; will be kRunState if the task is running, and if so the corresponding PC and SP values
- ; are invalid and will be returned as zero. If the task is blocked in normal execution
- ; then state->taskState.PC and state->taskState.SP will reflect the PC and SP at the time
- ; of the system call which caused the task to block. Similarly, if the task is blocked
- ; in a software interrupt, hence not running, then state->swiState.PC and state->swiState.SP
- ; will be nonzero.
- ;
- ;
- ; extern OSStatus DSGetTaskState(TaskID taskID, DSTaskState *state)
- ;
- IF GENERATINGCFM THEN
- IMPORT_CFM_FUNCTION DSGetTaskState
- ENDIF
-
- ;
- ; Create a write access right to the page for logical address dstAddr in address
- ; space addrSpaceID. This makes the page physically resident and prevents subsequent
- ; reads or writes of the page from or to backing storage. The access right is returned
- ; in memAccessID.
- ;
- ;
- ; extern OSStatus DSCreateMemoryAccess(AddressSpaceID addrSpaceID, LogicalAddress dstAddr, DSMemoryAccessID *memAccessID)
- ;
- IF GENERATINGCFM THEN
- IMPORT_CFM_FUNCTION DSCreateMemoryAccess
- ENDIF
-
- ;
- ; Modify the memory to which an access right has been obtained. memAccessID is the access
- ; right, dstAddr is the target address, srcDataPtr points to the source data to be written,
- ; and numBytes is the size of the write. The range [dstAddr..dstAddr + numBytes - 1] must lie
- ; entirely within the page specified by the access right. If the destination memory is code,
- ; processor caches will be synchronized appropriately.
- ;
- ;
- ; extern OSStatus DSWriteMemory(DSMemoryAccessID memAccessID, LogicalAddress dstAddr, void *srcDataPtr, ByteCount numBytes)
- ;
- IF GENERATINGCFM THEN
- IMPORT_CFM_FUNCTION DSWriteMemory
- ENDIF
-
- ;
- ; Delete an access right and allow normal backing storage activity for that page. memAccessID
- ; is the access right. Note: changes to the page up to this point will NOT be written to
- ; backing storage.
- ;
- ;
- ; extern OSStatus DSDeleteMemoryAccess(DSMemoryAccessID memAccessID)
- ;
- IF GENERATINGCFM THEN
- IMPORT_CFM_FUNCTION DSDeleteMemoryAccess
- ENDIF
-
- ;
- ; Read memory. srcAddr is the address to read from, addrSpaceID specifies the address space,
- ; dstDataPtr points to the debugger buffer into which to copy the data, and numBytes is the
- ; size of the read.
- ;
- ;
- ; extern OSStatus DSReadMemory(AddressSpaceID addrSpaceID, LogicalAddress srcAddr, void *dstDataPtr, ByteCount numBytes)
- ;
- IF GENERATINGCFM THEN
- IMPORT_CFM_FUNCTION DSReadMemory
- ENDIF
-
- ;
- ; Set a data breakpoint. addrSpaceID specifies the address space, which may or may not be
- ; used. breakAddr is the logical address to break on. numBytes is a hint as to the range
- ; of addresses to break on. The address range [breakAddr .. (breakAddr + numBytes -1)] must
- ; lie within the worst case data breakpoint resolution which the implmentation supports, as
- ; determined via DSGetDataBreakpointInformation. A data breakpoint hit will result in a
- ; memory access exception of type kDataBreakpointException. The implementation may cause
- ; excess exceptions which will have to be filtered out by the debugger, e.g. breakpoints
- ; may occur in the wrong address space or on an address which is outside the range specified
- ; but which lies within the resolution range supported by the implementation. To "fix up"
- ; a memory reference which triggered a data breakpoint exception without removing the
- ; data breakpoint, use DSReadMemory or DSWriteMemory. Data breakpoints may be disallowed
- ; on certain addresses which are used by system code; DSSetDataBreakpoint will return
- ; kernelInUseErr for such addresses.
- ;
- ;
- ; extern OSStatus DSSetDataBreakpoint(AddressSpaceID addrSpaceID, LogicalAddress breakAddr, ByteCount numBytes, DSDataBreakpointOptions options)
- ;
- IF GENERATINGCFM THEN
- IMPORT_CFM_FUNCTION DSSetDataBreakpoint
- ENDIF
-
- ;
- ; Get information about data breakpoint support. Returns the number of breakpoints available in
- ; the current implementation and the worst case address resolution of a data breakpoint.
- ;
- ;
- ; extern OSStatus DSGetDataBreakpointInformation(PBVersion version, DSDataBreakpointInformation *info)
- ;
- IF GENERATINGCFM THEN
- IMPORT_CFM_FUNCTION DSGetDataBreakpointInformation
- ENDIF
-
- ENDIF
- ENDIF ; __DEBUGGERSUPPORT__
-
-